#include "Shader.h"

#include <string>
// #include <fstream>
// #include <sstream>
#include <iostream>


#include "assglUtils.h"




GLuint Shader(const GLchar *vertexPath, const GLchar *fragmentPath)
{
	GLuint Program;
	// 1. Retrieve the vertex/fragment source code from filePath
	std::string vertexCode = ReadConfig(vertexPath);
	std::string fragmentCode = ReadConfig(fragmentPath);;
	// std::ifstream vShaderFile;
	// std::ifstream fShaderFile;
	// // ensures ifstream objects can throw exceptions:
	// vShaderFile.exceptions(std::ifstream::badbit);
	// fShaderFile.exceptions(std::ifstream::badbit);
	// try
	// {
	// 	// Open files
	// 	vShaderFile.open(vertexPath);
	// 	fShaderFile.open(fragmentPath);
	// 	std::stringstream vShaderStream, fShaderStream;
	// 	// Read file's buffer contents into streams
	// 	vShaderStream << vShaderFile.rdbuf();
	// 	fShaderStream << fShaderFile.rdbuf();
	// 	// close file handlers
	// 	vShaderFile.close();
	// 	fShaderFile.close();
	// 	// Convert stream into string
	// 	vertexCode = vShaderStream.str();
	// 	fragmentCode = fShaderStream.str();
	// 	// std::cout << "vertexCode:" << vertexCode << std::endl;
	// 	// std::cout << "fragmentCode:" << fragmentCode << std::endl;
	// }
	// catch (std::ifstream::failure e)
	// {
	// 	std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
	// }

	const GLchar *vShaderCode = vertexCode.c_str();
	const GLchar *fShaderCode = fragmentCode.c_str();
	// 2. Compile shaders
	GLuint vertex, fragment;
	GLint success;
	GLchar infoLog[512];
	// Vertex Shader
	vertex = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex, 1, &vShaderCode, NULL);
	glCompileShader(vertex);
	// Print compile errors if any
	glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertex, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
				  << infoLog << std::endl;
	}
	// Fragment Shader
	fragment = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment, 1, &fShaderCode, NULL);
	glCompileShader(fragment);
	// Print compile errors if any
	glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragment, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
				  << infoLog << std::endl;
	}
	// Shader Program
	Program = glCreateProgram();
	glAttachShader(Program, vertex);
	glAttachShader(Program, fragment);
	glLinkProgram(Program);
	// Print linking errors if any
	glGetProgramiv(Program, GL_LINK_STATUS, &success);
	if (!success)
	{
		glGetProgramInfoLog(Program, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
				  << infoLog << std::endl;
	}
	// Delete the shaders as they're linked into our program now and no longer necessery
	glDeleteShader(vertex);
	glDeleteShader(fragment);
	glUseProgram(Program);
	return Program;
}

// void Shader::Use()
// {
// 	glUseProgram(this->Program);
// } 